Repository navigation
perf(workers): use the final VM sweep during shutdown - #154
Merged
Merged
Conversation
Workers already finish environment and native-resource cleanup before retiring the VM. Avoid tracing and sweeping the heap immediately before its mandatory last-chance finalization, while preserving main-process collection and VM reference draining. Cover both Worker exit routes with heap-specific collection diagnostics.
steipete
force-pushed
the
claude/worker-heap-destruction-resume
branch
from
October 9, 2026 21:24
d8549f6 to
3851747
Compare
steipete
marked this pull request as ready for review
October 9, 2026 23:03
This was referenced Oct 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Worker shutdown performs a full tracing collection immediately before mandatory VM destruction. Move that preliminary collection to the main-process-only caller; Workers retain native/environment cleanup, code deletion, VM reference draining and last-chance finalization. No VM reuse or deferred acknowledged cleanup is introduced. This is rebased on the finalized ownership in #152 and the merged EventNames cleanup in #153.
The heap-specific regression fails the unchanged baseline at the extra full collection and passes both Worker exit routes. The current-head Mac run passes 271 Worker destruction/N-API/finalizer tests; the original eight-resource fixture remains 8/8 with zero fds, and WAL durability/reopen checks pass. Three OpenClaw cleanup/retirement files pass 13 tests on Node and 13 on the integration. The earlier frozen integration's surrounding Worker suites pass 303 tests with 20 existing gated skips.
Fixed paired integration measurements use the same frozen Bun/engine source and build settings in both arms. The companion engine change is openclaw/WebKit#31; no standalone-Bun attribution is inferred from combined numbers.
Each component cell has 20 observations in fixed forward/reverse order. Empty Mac point estimates are mixed; no universal speedup or Node parity is claimed. Separate phase logs show one preliminary collection before and zero after. Some destructor work moves into the final sweep rather than disappearing.
Full Gateway before/after AB/BA keeps the workload and 2,000 ms grace unchanged: 80/80 Linux workloads and 82 completed Mac workloads exit cleanly under the bound, with no kill attempt. Two Mac setup failures remain recorded. Linux medians improve 912.05→806.92 ms without trace and 997.33→874.01 ms with trace; Mac trace-off improves modestly, while trace-on has a small mixed regression. Both baseline and candidate meet the bound in this sample, so historical deadline misses are not proved eliminated by this change.
Calibrated ASAN tests retain the stronger ten-resource callback/thread/null-env/reentry assertions through 100 Workers. The frozen before/after comparison has only the known cache/parser leak sites. A fully rebuilt local composition with the separate cache/parser fixes passes 1,000 Workers on both routes and 100 retained-addon Workers per route under ASAN/LSAN, using only the inherited console suppression. Its unprimed exact-key string finalizes once with null env on the creator thread. No new suppression or lifetime-policy exception is introduced; the parser fix remains separate.
P2 review is scoped-clean. At head
3851747d2e747f7f92fed8cc9b0d1d7ce1bc4e2d, Linux/macOS native CI and Windows x64/ARM64 builds, smoke tests and compatibility tests pass, as do formatting and source/JavaScript lint. Windows attempt 1 stopped in provisioning on Docker Hub manifest/token timeouts before compilation or tests; only those interrupted infrastructure jobs were retried at the same head. The workflow usedpublish=false, with signing/publication skipped and no tag created. This draft remains unmerged and publishes no runtime. Upstream searches found no equivalent Worker-only collection-removal fix to port.Synthetic fixture and measurement procedure
Save these as
make-graph.pyandloaded-worker.mjsin a fresh directory. The graph has 1,200 modules with 24 exported functions each; the Worker retains another 100,000 objects. Startup/import is outside the parent termination interval.sqliteadds the same graph plus 2,000 in-memory rows;emptyimports no graph.Generate once with
python3 make-graph.py. For each runtime, invokeloaded-worker.mjs terminate 1 catalog(orworker-exit,empty,sqlite). Use fresh processes and private HOME/state/temp directories. Our comparison uses 20 fixed blocks per route/shape, with before/engine-only/combined/Node order on odd blocks and the reverse on even blocks; logging and profilers are disabled. Retain every attempt rather than replacing failures. Node reference is 26.10.0. These reduced fixtures do not replace full Gateway validation.